package transformers

import (
	"encoding/json"
	"fmt"

	"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
	"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
	"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
	v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"

	"github.com/jackc/pgx/v5/pgtype"
)

func ToEventList(events []*dbsqlc.Event) []gen.Event {
	res := make([]gen.Event, len(events))

	for i, event := range events {
		res[i] = ToEvent(event)
	}

	return res
}

func ToEvent(event *dbsqlc.Event) gen.Event {
	return gen.Event{
		Metadata: *toAPIMetadata(sqlchelpers.UUIDToStr(event.ID), event.CreatedAt.Time, event.UpdatedAt.Time),
		Key:      event.Key,
		TenantId: pgUUIDToStr(event.TenantId),
	}
}

func ToEventFromSQLC(eventRow *dbsqlc.ListEventsRow) (*gen.Event, error) {
	event := eventRow.Event

	var metadata map[string]interface{}

	if event.AdditionalMetadata != nil {
		err := json.Unmarshal(event.AdditionalMetadata, &metadata)
		if err != nil {
			return nil, err
		}
	}

	res := &gen.Event{
		Metadata:           *toAPIMetadata(pgUUIDToStr(event.ID), event.CreatedAt.Time, event.UpdatedAt.Time),
		Key:                event.Key,
		TenantId:           pgUUIDToStr(event.TenantId),
		AdditionalMetadata: &metadata,
	}

	res.WorkflowRunSummary = &gen.EventWorkflowRunSummary{
		Failed:    &eventRow.Failedruns,
		Running:   &eventRow.Runningruns,
		Succeeded: &eventRow.Succeededruns,
		Pending:   &eventRow.Pendingruns,
		Queued:    &eventRow.Queuedruns,
		Cancelled: &eventRow.Cancelledruns,
	}

	return res, nil
}

func ToEventFromSQLCV1(event *v1.EventWithPayload) (*gen.Event, error) {
	var metadata map[string]interface{}

	if event.EventAdditionalMetadata != nil {
		err := json.Unmarshal(event.EventAdditionalMetadata, &metadata)
		if err != nil {
			return nil, err
		}
	}

	res := &gen.Event{
		Metadata:           *toAPIMetadata(pgUUIDToStr(event.EventExternalID), event.EventSeenAt.Time, event.EventSeenAt.Time),
		Key:                event.EventKey,
		TenantId:           pgUUIDToStr(event.TenantID),
		AdditionalMetadata: &metadata,
	}

	res.WorkflowRunSummary = &gen.EventWorkflowRunSummary{
		Failed:    &event.FailedCount,
		Running:   &event.RunningCount,
		Succeeded: &event.CompletedCount,
		Pending:   &event.QueuedCount,
		Queued:    &event.QueuedCount,
		Cancelled: &event.CancelledCount,
	}

	return res, nil
}

func pgUUIDToStr(uuid pgtype.UUID) string {
	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid.Bytes[0:4], uuid.Bytes[4:6], uuid.Bytes[6:8], uuid.Bytes[8:10], uuid.Bytes[10:16])
}
